<?php
// +----------------------------------------------------------------------
// | Tag 标签服务
// +----------------------------------------------------------------------
// | 主要服务于Tag数据处理
// +----------------------------------------------------------------------
// | 错误编码头 235xxx
// +----------------------------------------------------------------------
namespace common\service;

use common\model\TagModel;
use common\model\TagRelationModel;
use Illuminate\Support\Arr;
use support\ErrorCode;
use support\SingletonTrait;

/**
 * 标签关联Service
 */
class TagRelationService
{
    use SingletonTrait;

    public function __construct()
    {
    }

    /**
     * 绑定标签
     * @param array $data
     * @param $userId
     * @return bool|int|mixed|string
     * @throws \Exception
     */
    public function bind(array $data, $userId)
    {
        $insertData = [];

        foreach ($data as $item) {
            $insertData[] = $this->buildInsertData($item, $userId);
        }

        $res = model(TagRelationModel::class)->addAll($insertData);
        if ($res === false) {
            throw_strack_exception('bind tag fail.', ErrorCode::TAG_BIND_FAIL);
        }

        return $res;
    }

    /**
     * 更新标签绑定
     * @param array $data
     * @param $userId
     * @return array|bool
     * @throws \Exception
     */
    public function updateBind(array $data, $userId)
    {
        // 获取是否存在记录
        $tagRelation = model(TagRelationModel::class)->where(['relation_type' => $data['relation_type'], 'relation_id' => $data['relation_id']])->find();
        if (!empty($tagRelation)) {
            // 存在绑定关系，则更新绑定关系
            $updateData = [
                'id' => $tagRelation['id'],
                'tag_id' => $data['tag_id']
            ];
            $res = model(TagRelationModel::class)->modifyItem($updateData);
        } else {
            // 不存在标签绑定，则建立绑定
            $insertData = $this->buildInsertData($data, $userId);
            $res = model(TagRelationModel::class)->addItem($insertData);
        }

        if ($res === false) {
            throw_strack_exception('unbind tag fail.', ErrorCode::TAG_BIND_FAIL);
        }

        return $res;
    }

    /**
     * 组装添加绑定的数据
     * @param $data
     * @param $userId
     * @return array
     */
    private function buildInsertData($data, $userId) {
        $insertData = Arr::only($data, ['tag_id', 'relation_id', 'relation_type', 'step_category_id', 'entity_ids']);
        if (!empty($insertData['entity_ids'])) {
            $insertData['entity_ids'] = is_array($insertData['entity_ids']) ? implode(',', $insertData['entity_ids']) : $insertData['entity_ids'];
        }
        $insertData['created'] = time();
        $insertData['created_by'] = $userId;
        return $insertData;
    }

    /**
     * 解除标签绑定
     * @param array $data
     * @return array|false|mixed|string|null
     */
    public function unbind(array $data)
    {
        $tagRelation = model(TagRelationModel::class)->where(['relation_type' => $data['relation_type'], 'relation_id' => $data['relation_id']])->find();
        if (!empty($tagRelation)) {
            $delRes = model(TagRelationModel::class)->where(['relation_type' => $data['relation_type'], 'relation_id' => $data['relation_id']])->delete();
            if ($delRes === false) {
                throw_strack_exception('unbind tag fail.', ErrorCode::TAG_UNBIND_FAIL);
            }
        }
        return $tagRelation;
    }

    /**
     * 根据关联id获取标签
     * @param array $params
     * @return array|false|mixed|string
     */
    public function getTagsByRelationIds(array $params)
    {
        $relationIds = array_column($params, 'relation_id');
        $relationTypes = array_column($params, 'relation_type');

        $list = model(TagRelationModel::class)
            ->where(['relation_id' => ['IN', $relationIds], 'relation_type' => ['IN', array_unique($relationTypes)]])
            ->field(['tag_id'])
            ->select();
        $tagIds = array_column($list, 'tag_id');
        $tags = model(TagModel::class)->where(['id' => ['IN', array_unique($tagIds)]])->select();
        $tagMap = array_column($tags, 'name', 'id');

        foreach ($list as &$item) {
            $item['tag_name'] = $tagMap[$item['tag_id']] ?? '';
        }
        return $list;
    }

    /**
     * 需求绑定标签
     * @param array $noteInfo 需求信息 {“id”: 需求id, "demand_type"}
     * @param array $noteEntityRelationList 需求与实体绑定信息
     * @return bool|int|mixed|string
     * @throws \Exception
     */
    public function noteBindTag(array $noteInfo, array $noteEntityRelationList)
    {
        $insertData = [];
        $tagInfo = model(TagModel::class)->where(['name' => trim($noteInfo['reason_type'])])->field(['id', 'name'])->find();
        if (empty($tagInfo)) {
            throw_strack_exception('tag not found.', ErrorCode::TAG_NOT_FOUND);
        }

        foreach ($noteEntityRelationList as $item) {
            if (!isset($item['step_category_id'])) {
                continue;
            }

            $insertData[] = [
                'tag_id' => $tagInfo['id'],
                'relation_id' => $noteInfo['id'],
                'relation_type' => $noteInfo['demand_type'] == 'demand' ? TagRelationModel::RELATION_TYPE_DEMAND : TagRelationModel::RELATION_TYPE_WORK_ORDER,
                'step_category_id' => $item['step_category_id'],
                'entity_ids' => $item['entity_id'],
                'created' => time(),
                'created_by' => $noteInfo['created_by']
            ];
        }

        if (empty($insertData)) {
            return [];
        }

        $addRes = model(TagRelationModel::class)->addAll($insertData);
        if ($addRes === false) {
            throw_strack_exception('bind tag fail.', ErrorCode::TAG_BIND_FAIL);
        }

        return $addRes;
    }
}
